/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package xjson.engine;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import xjson.JEntity;

/**
 *
 * @author olawale
 */
public class Store {

    public Store(){
        storeMap = new HashMap();
        read = 0;get = 0; save = 0;
    }
    private static Store store;

    private PrintWriter pw;
    private BufferedReader br;
    private HashMap<String, JSONArray> storeMap;
    private static final String jkey = "jkey";

    int read, get, save;

    static Store getInstance(){
        if(store == null)
            store = new Store();
        return store;
    }

    private JSONArray readFile(Class cl){
        System.out.println("---READ FILE " + ++read);
        try {
            File file = new File(getFileName(cl));
            if(!file.exists())
                file.createNewFile();
            br = new BufferedReader(new FileReader(file));
            String rec = br.readLine();
            JSONArray ja = null;
            if(rec == null || rec.isEmpty())
                return new JSONArray();
            else
                ja = new JSONArray(rec);
            return ja;
        } catch (Exception ex) {
            Logger.getLogger(Store.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    void saveFile(JSONArray array, Class cl){
        System.out.println("+++SAVE FILE " + ++save);
        FileOutputStream fos = null;
        try {
            File file = new File(getFileName(cl));
//            fos = new FileOutputStream(file);
            pw = new PrintWriter(file);
            pw.println(array.toString());
            pw.flush();
        } catch (Exception ex) {
            Logger.getLogger(Store.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
//            try {
//                fos.close();
//            } catch (IOException ex) {
//                Logger.getLogger(Store.class.getName()).log(Level.SEVERE, null, ex);
//            }
        }
    }

    public HashMap<Integer, JSONObject> getAllMap(Class cl){
        JSONArray array = store.getFile(cl);
        HashMap<Integer, JSONObject> map = new HashMap();
        for(int i = 0; i < array.length(); i++){
            try {
                int key = array.getJSONObject(i).optInt(jkey, -1);
                if(key == -1) continue;
                map.put(key, array.getJSONObject(i));
            } catch (JSONException ex) {
                Logger.getLogger(Dal.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return map;
    }

    JSONArray getFile(Class cl){
        System.out.println("___GET FILE " + ++get);
        try {
            String key = getFileName(cl);
            if(storeMap.containsKey(key))
                return storeMap.get(key);
            else{
                JSONArray value = readFile(cl);
                storeMap.put(key, value);
                return value;
            }
        } catch (Exception ex) {
            Logger.getLogger(Store.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private String getFileName(Class cl) throws Exception{
        JEntity jnode = (JEntity) cl.getAnnotation(JEntity.class);
        if(jnode == null){
            throw new Exception(cl + " is not a valid jentity class");
        }
        String fileName = (jnode.fileName().isEmpty()) ? cl.getName().replace('.', '-') : jnode.fileName();
        return fileName + ".jsn";
    }
}
